import { WsConnection, WsServer } from "tsrpc";
import { ServiceType } from "../shared/protocols/serviceProto";
import { Test } from "../utils/Classes/Test";
import { Live, player } from '../utils/Classes/Live';
import { Wsserver } from '../index';
import { MsgLiveTarget } from "../shared/protocols/AMessages/Live/MsgLiveTarget";
// import { callbackPromise } from "nodemailer/lib/shared";
import { users,liveStudent } from '../shared/types/user';
/*
 * @Date: 2023-02-12 20:10:53
 * @LastEditors: Zireael 1193875164@qq.com
 * @LastEditTime: 2023-03-27 16:59:19
 * @FilePath: \A19\backend\src\flowNodes\studentOffline.ts
 */
export function onStudentOffline(wsServer:WsServer<ServiceType>){
    wsServer.flows.postDisconnectFlow.push((v)=>{
        // console.log("connId: ",v.conn.id);
        // Test.tests.forEach((test,i,arr) =>{
            // const index = test.students.findIndex(stu => stu.connection.id === v.conn.id)    
            // test.students.splice(index,1)
            // console.log("remained: ",test.students.length);
            
        // })

        //学生离开考试
        Test.tests.find(test =>{
            if(test.students.has(v.conn.id)){//学生从考试退出
                //a student left the test
                //给监考老师发送信息
                if(test.teacher !== undefined){
                    // test.teacher.connection.sendMsg('AMessages/Test/StudentStatus',{
                    //     students:[...test.students.values()].map(student => student.student)
                    // })
                    test.teacher.connection.sendMsg('AMessages/Test/ConnectInfo',{
                        info:'disconnected',
                        student:test.students.get(v.conn.id)?.student
                    })
                }
                test.students.delete(v.conn.id)
                console.log("remainStudent: ",test.students.size," teacher: ",test.teacher?.teacher.name);
                return true
            }
            return false
        })
        
        //学生退出直播
        Live.lives.find(async live =>{
            const student = live.students.find(stu => stu.connection?.id === v.conn.id)
            if(student){
                //确定学生位置
                const rootNodes = [...live.connectionMap.values()]
                const rootNode = rootNodes.find(node => node.node.id === v.conn.id)
                if(rootNode){
                    //根节点之一
                    console.log('根节点之一');
                    const newRootNode = rootNode.afters.shift()
                    if(newRootNode){
                        //有后续节点
                        //清除根节点链接 用afters中的第一个节点代替
                        rootNode.node = newRootNode.node
                        //通知host点连接代替节
                        //找到这个学生
                        const student = live.students.find(s => s.connection?.id === newRootNode.node.id) as liveStudent
                        await live.host.connection.sendMsg('AMessages/Live/LiveTarget',{
                            target:student._id
                        } as MsgLiveTarget)

                        if(newRootNode.after){
                            //新根节点有after
                            //让某一个节点重新链接after
                            const student = live.students.find(s => s.connection?.id === newRootNode.after?.id) as liveStudent
                            const target = live.getTarget(student._id,student.connection as WsConnection)
                            await target.sendMsg('AMessages/Live/LiveTarget',{
                                target:student._id
                            } as MsgLiveTarget)
                        }
                        else{
                            //新根节点没有afer
                        }
                    }
                    else{
                        //没有后续节点
                        //清除根节点
                        const key = [...live.connectionMap.keys()].find(key => live.connectionMap.get(key)?.node.id === rootNode.node.id)
                        if(key) live.connectionMap.delete(key)
                    }
                }
                else{
                    //根节点的after中的节点
                    console.log('根节点的afters中的节点'); 
                    rootNodes.forEach(rootNode =>{
                        rootNode.afters.reduce((previousValue,currentValue,currentIndex,arr)=>{
                            if(currentValue.node.id === student.connection?.id){
                                //这个节点的主节点
                                //前一个连接后一个
                                const next = arr.at(currentIndex + 1)
                                if(next){
                                    //有后一个
                                    const nextStu = live.students.find(s => s.connection?.id === next.node.id);
                                    if(nextStu !== undefined)
                                        (previousValue.node as WsConnection<ServiceType>).sendMsg('AMessages/Live/LiveTarget',{
                                            target:nextStu._id
                                        })
                                    arr.splice(currentIndex,1)
                                }
                                else{
                                    //没有后一个 current是最后一个
                                    arr.pop()
                                }
                                if(currentValue.after){
                                    //如果有after
                                    const student = live.students.find(s => s.connection?.id === currentValue.after?.id)
                                    if(student){
                                        const target = live.getTarget(student._id,student?.connection as WsConnection)
                                        target.sendMsg('AMessages/Live/LiveTarget',{
                                            target:student._id
                                        })
                                    }
                                }
                            }
                            else if(currentValue.after?.id === student.connection?.id){
                                //这个节点的after
                                currentValue.after = undefined
                            }
                            else{
                                //不是这个节点
                            }
                            return currentValue
                        },{ node:rootNode.node, after:undefined })
                    })
                }
                
                //student列表 + 通知host
                student.status = 'offline'
                student.connection = undefined
                // await live.host.connection.sendMsg('AMessages/Live/StuStatus',{
                //     student:student._id,
                //     course:live.courseId,
                //     status:'disconnect'
                // } as MsgStuStatus)
                const connections = new Array<WsConnection>
                connections.push(live.host.connection)
                live.students.forEach(s =>{
                    if(s.connection){
                        connections.push(s.connection)
                    }
                })
                await Wsserver.broadcastMsg('AMessages/Live/StuStatus',{
                    student:student._id,
                    course:live.courseId,
                    status:'disconnect'
                },connections)

                await live.sendTalk(student,"离开课堂",'disconnect')

                return true
            }
            return false
        })
        
        return v
    })

    wsServer.flows.postDisconnectFlow.push(v =>{
        let index = -1
        let offStudent:player
        const live = Live.lives.find((live) => {
            index = live.players.findIndex(player => player.connection.id === v.conn.id)
            if(index === -1) return false
            else{
                offStudent = live.players.splice(index,1)[0]
                console.log(offStudent.playerName + " offline");
                return true
            }
        })
        if(live){
            Wsserver.broadcastMsg('AMessages/Game/PlayerLeave',{
                playerId:offStudent!.playerId,
                liveId:live.courseId
            },live.players.map(s => s.connection))
        }
        
       
        return v
    })
}